Add SlackAgent

The SlackAgent lets you receive events and send notifications to slack

Tonmoy Saikia 10 ans auparavant
Parent
Commettre
ed4cfbc440
4 fichiers modifiés avec 129 ajouts et 0 suppressions
  1. 1 0
      Gemfile
  2. 2 0
      Gemfile.lock
  3. 62 0
      app/models/agents/slack_agent.rb
  4. 64 0
      spec/models/agents/slack_agent_spec.rb

+ 1 - 0
Gemfile

@@ -70,6 +70,7 @@ gem 'em-http-request', '~> 1.1.2'
70 70
 gem 'weibo_2', '~> 0.1.4'
71 71
 gem 'hipchat', '~> 1.1.0'
72 72
 gem 'xmpp4r',  '~> 0.5.6'
73
+gem 'slack-notifier', '~> 0.5.0'
73 74
 
74 75
 gem 'therubyracer', '~> 0.12.1'
75 76
 

+ 2 - 0
Gemfile.lock

@@ -245,6 +245,7 @@ GEM
245 245
       multi_json
246 246
       simplecov-html (~> 0.8.0)
247 247
     simplecov-html (0.8.0)
248
+    slack-notifier (0.5.0)
248 249
     slop (3.5.0)
249 250
     sprockets (2.11.0)
250 251
       hike (~> 1.2)
@@ -355,6 +356,7 @@ DEPENDENCIES
355 356
   sass-rails (~> 4.0.0)
356 357
   select2-rails (~> 3.5.4)
357 358
   shoulda-matchers
359
+  slack-notifier (~> 0.5.0)
358 360
   therubyracer (~> 0.12.1)
359 361
   twilio-ruby (~> 3.11.5)
360 362
   twitter (~> 5.8.0)

+ 62 - 0
app/models/agents/slack_agent.rb

@@ -0,0 +1,62 @@
1
+module Agents
2
+  class SlackAgent < Agent
3
+    include LiquidInterpolatable
4
+    cannot_be_scheduled!
5
+    cannot_create_events!
6
+
7
+    DEFAULT_WEBHOOK = 'incoming-webhook'
8
+
9
+    description <<-MD
10
+      The SlackAgent lets you receive events and send notifications to [slack](https://slack.com/).
11
+
12
+      To get started, you will first need to setup an incoming webhook.
13
+      Go to, https://`your_team_name`.slack.com/services/new/incoming-webhook,
14
+      choose a default channel and add the integration.
15
+
16
+      Your webhook URL will look like:
17
+
18
+      https://`your_team_name`.slack.com/services/hooks/incoming-webhook?token=`your_auth_token`
19
+
20
+      Once the webhook has been setup it can be used to post to other channels or ping team members.
21
+      To send a private message to team-mate, assign his username as `@username` to the channel option.
22
+      To communicate with a different webhook on slack, assign your custom webhook name to the webhook option.
23
+      Messages can also be formatted using [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid)
24
+    MD
25
+
26
+    def default_options
27
+      {
28
+        'team_name' => 'your_team_name',
29
+        'auth_token' => 'your_auth_token',
30
+        'channel' => '#general',
31
+        'username' => "Huginn",
32
+        'message' => "Hey there, It's Huginn",
33
+        'webhook' => DEFAULT_WEBHOOK
34
+      }
35
+    end
36
+
37
+    def validate_options
38
+      errors.add(:base, "auth_token is required") unless options['auth_token'].present?
39
+      errors.add(:base, "team_name is required") unless options['team_name'].present?
40
+      errors.add(:base, "channel is required") unless options['channel'].present?
41
+    end
42
+
43
+    def working?
44
+      received_event_without_error?
45
+    end
46
+
47
+    def webhook
48
+      options[:webhook].present? ? options[:webhook] : DEFAULT_WEBHOOK
49
+    end
50
+
51
+    def slack_notifier
52
+      @slack_notifier ||= Slack::Notifier.new(options[:team_name], options[:auth_token], webhook)
53
+    end
54
+
55
+    def receive(incoming_events)
56
+      incoming_events.each do |event|
57
+        opts = interpolate_options options, event.payload
58
+        slack_notifier.ping opts[:message], channel: opts[:channel], username: opts[:username]
59
+      end
60
+    end
61
+  end
62
+end

+ 64 - 0
spec/models/agents/slack_agent_spec.rb

@@ -0,0 +1,64 @@
1
+require 'spec_helper'
2
+require 'models/concerns/liquid_interpolatable'
3
+
4
+describe Agents::SlackAgent do
5
+  it_behaves_like LiquidInterpolatable
6
+
7
+  before(:each) do
8
+    @valid_params = {
9
+                      'auth_token' => 'token',
10
+                      'team_name' => 'testteam',
11
+                      'channel' => '#random',
12
+                      'username' => "{{username}}",
13
+                      'message' => "{{message}}"
14
+                    }
15
+
16
+    @checker = Agents::SlackAgent.new(:name => "slacker", :options => @valid_params)
17
+    @checker.user = users(:jane)
18
+    @checker.save!
19
+
20
+    @event = Event.new
21
+    @event.agent = agents(:bob_weather_agent)
22
+    @event.payload = { :channel => '#random', :message => 'Looks like its going to rain', username: "Huggin user"}
23
+    @event.save!
24
+  end
25
+
26
+  describe "validating" do
27
+    before do
28
+      expect(@checker).to be_valid
29
+    end
30
+
31
+    it "should require a auth_token" do
32
+      @checker.options['auth_token'] = nil
33
+      expect(@checker).not_to be_valid
34
+    end
35
+
36
+    it "should require a channel" do
37
+      @checker.options['channel'] = nil
38
+      expect(@checker).not_to be_valid
39
+    end
40
+
41
+    it "should require a team_name" do
42
+      @checker.options['team_name'] = 'nil'
43
+      expect(@checker).to be_valid
44
+    end
45
+  end
46
+  describe "#receive" do
47
+    it "receive an event without errors" do
48
+      any_instance_of(Slack::Notifier) do |obj|
49
+        mock(obj).ping(@event.payload[:message],
50
+                       channel: @event.payload[:channel],
51
+                       username: @event.payload[:username]
52
+                      )
53
+      end
54
+      expect(@checker.receive([@event])).to_not raise_error
55
+    end
56
+  end
57
+
58
+  describe "#working?" do
59
+    it "should call received_event_without_error?" do
60
+      mock(@checker).received_event_without_error?
61
+      @checker.working?
62
+    end
63
+  end
64
+end